home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_jnos / j109lxa4.tgz / j109lxa4.tar / glob.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  5KB  |  215 lines

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <string.h>
  4. #include <dirent.h>
  5. #include <time.h>
  6. #include <sys/stat.h>
  7.  
  8. #define GLOB_INTERNAL
  9. #include "dirutil.h"
  10.  
  11. extern void j_free __ARGS((void *));
  12.  
  13. #ifdef __cplusplus
  14. extern "C" {
  15. #endif
  16. extern uid_t geteuid __ARGS((void));
  17. extern gid_t getegid __ARGS((void));
  18. #ifdef __cplusplus
  19. }
  20. #endif
  21.  
  22. /*
  23.  * Second approximation of glob routine for JNOS/Linux
  24.  */
  25.  
  26. static int ff1(char *, char *, char *, struct ffblk *, int);
  27.  
  28. static char *
  29. __ff_cat(char *pfx, char *sfx)
  30. {
  31.     static char buf[1024];
  32.  
  33.     buf[0] = '\0';
  34.     if (pfx && *pfx)
  35.     strcat(buf, pfx);
  36.     if (pfx && *pfx && sfx && *sfx && (*pfx != '/' || pfx[1] != '\0'))
  37.     strcat(buf, "/");
  38.     if (sfx && *sfx)
  39.     strcat(buf, sfx);
  40.     return buf;
  41. }
  42.  
  43. int
  44. findnext(struct ffblk *ff)
  45. {
  46.     struct stat sb;
  47.     char *path;
  48.     int m;
  49.  
  50.     /* special-case literal: if there's no pattern, just close the ff */
  51.     if (!ff->ff_pat || !ff->ff_dir)
  52.     return -1;
  53.     for (;;)
  54.     {
  55.     while ((ff->ff_cur = readdir(ff->ff_dir)) &&
  56.         !wildmat(ff->ff_cur->d_name, ff->ff_pat, 0))
  57.         ;
  58.     if (!ff->ff_cur)
  59.     {
  60.         closedir(ff->ff_dir);
  61.         ff->ff_dir = 0;
  62.         j_free(ff->ff_pat);
  63.         j_free(ff->ff_pfx);
  64.         return -1;
  65.     }
  66.     path = strdup(__ff_cat(ff->ff_pfx, ff->ff_cur->d_name));
  67.     if ((*ff->ff_cur->d_name == '.' && !(ff->ff_sattr & FA_HIDDEN)) ||
  68.         stat(path, &sb) == -1 ||
  69.         (!(ff->ff_sattr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  70.         (!S_ISREG(sb.st_mode) && !(ff->ff_sattr & FA_SYSTEM) &&
  71.          !(ff->ff_sattr & FA_HIDDEN)))
  72.     {
  73.         j_free(path);
  74.         continue;
  75.     }
  76.     j_free(path);
  77.     if (geteuid() == sb.st_uid)
  78.         m = 0700;
  79.     else if (getegid() == sb.st_gid)
  80.         m = 0070;
  81.     else
  82.         m = 0007;
  83.     if (!(sb.st_mode & m) && !(ff->ff_sattr & FA_SYSTEM))
  84.         continue;
  85.     ff->ff_ftime = *localtime(&sb.st_mtime);
  86.     ff->ff_fsize = sb.st_size;
  87.     if (S_ISDIR(sb.st_mode))
  88.         ff->ff_attrib = FA_DIREC;
  89.     else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  90.         ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  91.     else
  92.         ff->ff_attrib = FA_NORMAL;
  93.     if (*ff->ff_cur->d_name == '.')
  94.         ff->ff_attrib |= FA_HIDDEN;
  95.     if (!(sb.st_mode & m & 0222))
  96.         ff->ff_attrib |= FA_RDONLY;
  97.     strcpy(ff->ff_name, ff->ff_cur->d_name);
  98.     return 0;
  99.     }
  100. }
  101.  
  102. static int
  103. ff1(char *prefix, char *dir, char *pat, struct ffblk *ff, int attr)
  104. {
  105.     char *pp, *cp, *ep, *xp, *bp;
  106.     struct stat sb;
  107.     int m;
  108.  
  109.     ff->ff_pfx = strdup(__ff_cat(prefix, dir));
  110.     ff->ff_pat = 0;
  111.     ff->ff_dir = 0;
  112.     ff->ff_cur = 0;
  113.     ff->ff_name[0] = '\0';
  114.     ff->ff_sattr = attr;
  115.     cp = ep = pp = strdup(pat);
  116.     xp = 0;
  117.     bp = "";
  118.     for (; *cp; cp = ep)
  119.     {
  120.     while (*ep && *ep != '/') /* extract next component */
  121.     {
  122.         if (*ep == '?' || *ep == '*' || *ep == '[')
  123.         xp = ep;    /* record presence of wildcard characters */
  124.         ep++;
  125.     }
  126.     if (*ep)
  127.         *ep++ = '\0';
  128.     if (xp)            /* if we got a wildcard, abort */
  129.         break;
  130.     if (!*cp || strcmp(cp, ".") == 0) /* prune null components */
  131.         continue;
  132.     xp = ff->ff_pfx;    /* append component to prefix */
  133.     ff->ff_pfx = strdup(__ff_cat(xp, cp));
  134.     j_free(xp);
  135.     xp = 0;
  136.     bp = cp;
  137.     }
  138.     if (!xp)            /* no wildcards; just return it */
  139.     {
  140.     strcpy(ff->ff_name, bp);
  141.     if ((*bp == '.' && !(attr & FA_HIDDEN)) ||
  142.         stat(ff->ff_pfx, &sb) == -1 ||
  143.         (!(attr & FA_DIREC) && S_ISDIR(sb.st_mode)) ||
  144.         (!S_ISREG(sb.st_mode) && !(attr & FA_SYSTEM) &&
  145.          !(attr & FA_HIDDEN)))
  146.     {
  147.         j_free(pp);
  148.         j_free(ff->ff_pfx);
  149.         return -1;
  150.     }
  151.     /* unreadable files are system files */
  152.     /* don't check for root:  if you run nos as root you're dead anyway */
  153.     if (geteuid() == sb.st_uid)
  154.         m = 0700;
  155.     else if (getegid() == sb.st_gid) /* WARNING: ignores group vec */
  156.         m = 0070;
  157.     else
  158.         m = 0007;
  159.     if (!(attr & FA_SYSTEM) && !(sb.st_mode & m))
  160.     {
  161.         j_free(ff->ff_pfx);
  162.         j_free(pp);
  163.         return -1;
  164.     }
  165.     ff->ff_ftime = *localtime(&sb.st_mtime);
  166.     ff->ff_fsize = sb.st_size;
  167.     if (S_ISDIR(sb.st_mode))
  168.         ff->ff_attrib = FA_DIREC;
  169.     else if (!S_ISREG(sb.st_mode) || !(sb.st_mode & m))
  170.         ff->ff_attrib = FA_SYSTEM | FA_HIDDEN;
  171.     else
  172.         ff->ff_attrib = FA_NORMAL;
  173.     if (*bp == '.')
  174.         ff->ff_attrib |= FA_HIDDEN;
  175.     if (!(sb.st_mode & m & 0222))
  176.         ff->ff_attrib |= FA_RDONLY;
  177.     j_free(pp);
  178.     j_free(ff->ff_pfx);
  179.     ff->ff_pfx = 0;
  180.     return 0;
  181.     }
  182.     if (*ep)            /* no subdirs this version */
  183.     {
  184.     j_free(ff->ff_pfx);
  185.     j_free(pp);
  186.     return -1;
  187.     }
  188.     ff->ff_pat = strdup(cp);    /* the wildcarded component */
  189.     j_free(pp);
  190.     if (!(ff->ff_dir = opendir(*ff->ff_pfx? ff->ff_pfx: ".")))
  191.     {
  192.     j_free(ff->ff_pat);
  193.     j_free(ff->ff_pfx);
  194.     return -1;
  195.     }
  196.     return findnext(ff);
  197. }
  198.  
  199. int
  200. findfirst(char *pat, struct ffblk *ff, int attr)
  201. {
  202.     return ff1((*pat == '/'? "/": ""), "", (*pat == '/'? pat + 1: pat),
  203.          ff, attr);
  204. }
  205.  
  206. void
  207. findlast(struct ffblk *ff)
  208. {
  209.     if (!ff->ff_dir)
  210.       return;
  211.     closedir(ff->ff_dir);
  212.     j_free(ff->ff_pat);
  213.     j_free(ff->ff_pfx);
  214. }
  215.